package io.renren.wechat.controller;

import io.renren.wechat.common.aes.AesException;
import io.renren.wechat.common.aes.WXBizMsgCrypt;
import io.renren.wechat.config.WechatProperties;
import io.renren.wechat.service.suite.SuiteTicketService;
import io.renren.wechat.support.WXPayUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.Map;


/**
 * 指令回调URL
 */
@Controller
@RequestMapping("/wechat/callback")
public class WechatCallbackController {
    private static final Logger LOGGER = LoggerFactory.getLogger(WechatCallbackController.class);
    private WXBizMsgCrypt bizMsgCrypt;
    private WechatProperties wechatProperties;
    private SuiteTicketService suiteTicketService;



    @GetMapping("/event")
    public ResponseEntity<String> recvMsgNotify(@RequestParam("msg_signature") String msgSignature,
                                                @RequestParam("timestamp") String timestamp,
                                                @RequestParam("nonce") String nonce,
                                                @RequestParam("echostr") String echoStr) {
        LOGGER.info("recvMsgNotify parameters: recvMsgNotify=[{}], timestamp=[{}], nonce=[{}], echostr=[{}]",
                msgSignature, timestamp, nonce, echoStr);
        try {
            final String plainMsgText = bizMsgCrypt.VerifyURL(msgSignature, timestamp, nonce, echoStr);
            LOGGER.info("recvMsgNotify plainMsgText: [{}]", plainMsgText);

            return ResponseEntity.ok().body(plainMsgText);
        } catch (AesException e) {
            LOGGER.error("recvMsgNotify failed", e);
        }

        return ResponseEntity.badRequest().build();
    }

    @PostMapping("/event")
    public ResponseEntity<String> recvDataNotify(@RequestParam("msg_signature") String msgSignature,
                                                 @RequestParam("timestamp") String timestamp,
                                                 @RequestParam("nonce") String nonce,
                                                 RequestEntity<String> request) throws Exception {
        LOGGER.debug("recvMsgNotify parameters: recvMsgNotify=[{}], timestamp=[{}], nonce=[{}]",
                msgSignature, timestamp, nonce);
        final String requestBody = request.getBody();

        final String xmlMsg = bizMsgCrypt.DecryptMsg(msgSignature, timestamp, nonce, requestBody);
        LOGGER.debug("request xml msg: {}", xmlMsg);

        final Map<String, String> dataMap = WXPayUtil.xmlToMap(xmlMsg);
        final String infoType = dataMap.get("InfoType");
        LOGGER.debug("recv data infoType: {}", infoType);

        /* 推送suite_ticket */
        if (StringUtils.equalsIgnoreCase(infoType, "suite_ticket")) { // 推送suite_ticket
            suiteTicketService.cacheSuiteTicket(dataMap.get("SuiteId"), dataMap.get("SuiteTicket"));
        } else if (StringUtils.equalsIgnoreCase(infoType, "create_auth")) { // 授权成功通知
            suiteTicketService.cacheAuthCode(dataMap.get("SuiteId"), dataMap.get("AuthCode"));
        } else if (StringUtils.equalsIgnoreCase(infoType, "change_auth")) { // 变更授权通知

        } else if (StringUtils.equalsIgnoreCase(infoType, "cancel_auth")) { // 变更授权通知

        } else if (StringUtils.equalsIgnoreCase(infoType, "change_contact")) { // 变更授权通知
            /* changeType=[create_user, update_user, delete_user, update_tag, delete_party, update_party, create_party] */
            final String changeType = dataMap.get("ChangeType");


        }

        return ResponseEntity.ok().body("success");
    }

    @Autowired
    public void setBizMsgCrypt(WXBizMsgCrypt bizMsgCrypt) {
        this.bizMsgCrypt = bizMsgCrypt;
    }

    @Autowired
    public void setWechatProperties(WechatProperties wechatProperties) {
        this.wechatProperties = wechatProperties;
    }

    @Autowired
    public void setSuiteTicketService(SuiteTicketService suiteTicketService) {
        this.suiteTicketService = suiteTicketService;
    }
}
